home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SRC / ZOOM.C < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-28  |  9.9 KB  |  422 lines

  1. /* $Id: zoom.c,v 3.3 1998/03/28 03:57:13 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: zoom.c,v $
  26.  * Revision 3.3  1998/03/28 03:57:13  brianp
  27.  * added CONST macro to fix IRIX compilation problems
  28.  *
  29.  * Revision 3.2  1998/03/15 17:56:56  brianp
  30.  * added a const in gl_write_zoomed_rgba_span()
  31.  *
  32.  * Revision 3.1  1998/02/08 20:22:40  brianp
  33.  * added gl_write_zoomed_rgb_span()
  34.  *
  35.  * Revision 3.0  1998/02/01 22:13:55  brianp
  36.  * initial rev
  37.  *
  38.  */
  39.  
  40.  
  41. #ifdef PC_HEADER
  42. #include "all.h"
  43. #else
  44. #include <assert.h>
  45. #include "macros.h"
  46. #include "span.h"
  47. #include "stencil.h"
  48. #include "zoom.h"
  49. #endif
  50.  
  51.  
  52.  
  53. /*
  54.  * Write a span of pixels to the frame buffer while applying a pixel zoom.
  55.  * This is only used by glDrawPixels and glCopyPixels.
  56.  * Input:  n - number of pixels in input row
  57.  *         x, y - destination of the span
  58.  *         z - depth values for the span
  59.  *         red, green, blue, alpha - array of colors
  60.  *         y0 - location of first row in the image we're drawing.
  61.  */
  62. void
  63. gl_write_zoomed_rgba_span( GLcontext *ctx,
  64.                            GLuint n, GLint x, GLint y, const GLdepth z[],
  65.                            CONST GLubyte rgba[][4], GLint y0 )
  66. {
  67.    GLint m;
  68.    GLint r0, r1, row, r;
  69.    GLint i, j, skipcol;
  70.    GLubyte zrgba[MAX_WIDTH][4];  /* zoomed pixel colors */
  71.    GLdepth zdepth[MAX_WIDTH];  /* zoomed depth values */
  72.    GLint maxwidth = MIN2( ctx->Buffer->Width, MAX_WIDTH );
  73.    const GLuint *srcRGBA32 = (const GLuint *) rgba;
  74.    GLuint *dstRGBA32 = (GLuint *) zrgba;
  75.  
  76.    /* compute width of output row */
  77.    m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
  78.    if (m==0) {
  79.       return;
  80.    }
  81.    if (ctx->Pixel.ZoomX<0.0) {
  82.       /* adjust x coordinate for left/right mirroring */
  83.       x = x - m;
  84.    }
  85.  
  86.    /* compute which rows to draw */
  87.    row = y-y0;
  88.    r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
  89.    r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
  90.    if (r0==r1) {
  91.       return;
  92.    }
  93.    else if (r1<r0) {
  94.       GLint rtmp = r1;
  95.       r1 = r0;
  96.       r0 = rtmp;
  97.    }
  98.  
  99.    /* return early if r0...r1 is above or below window */
  100.    if (r0<0 && r1<0) {
  101.       /* below window */
  102.       return;
  103.    }
  104.    if (r0>=ctx->Buffer->Height && r1>=ctx->Buffer->Height) {
  105.       /* above window */
  106.       return;
  107.    }
  108.  
  109.    /* check if left edge is outside window */
  110.    skipcol = 0;
  111.    if (x<0) {
  112.       skipcol = -x;
  113.       m += x;
  114.    }
  115.    /* make sure span isn't too long or short */
  116.    if (m>maxwidth) {
  117.       m = maxwidth;
  118.    }
  119.    else if (m<=0) {
  120.       return;
  121.    }
  122.  
  123.    assert( m <= MAX_WIDTH );
  124.  
  125.    /* zoom the span horizontally */
  126.    if (ctx->Pixel.ZoomX==-1.0F) {
  127.       /* n==m */
  128.       for (j=0;j<m;j++) {
  129.          i = n - (j+skipcol) - 1;
  130.          dstRGBA32[j] = srcRGBA32[i];
  131.          zdepth[j] = z[i];
  132.       }
  133.    }
  134.    else {
  135.       GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
  136.       for (j=0;j<m;j++) {
  137.          i = (j+skipcol) * xscale;
  138.          if (i<0)  i = n + i - 1;
  139.          dstRGBA32[j] = srcRGBA32[i];
  140.          zdepth[j] = z[i];
  141.       }
  142.    }
  143.  
  144.    /* write the span */
  145.    for (r=r0; r<r1; r++) {
  146.       gl_write_rgba_span( ctx, m, x+skipcol, r, zdepth, zrgba, GL_BITMAP );
  147.    }
  148. }
  149.  
  150.  
  151.  
  152. void
  153. gl_write_zoomed_rgb_span( GLcontext *ctx,
  154.                           GLuint n, GLint x, GLint y, const GLdepth z[],
  155.                           CONST GLubyte rgb[][3], GLint y0 )
  156. {
  157.    GLint m;
  158.    GLint r0, r1, row, r;
  159.    GLint i, j, skipcol;
  160.    GLubyte zrgba[MAX_WIDTH][4];  /* zoomed pixel colors */
  161.    GLdepth zdepth[MAX_WIDTH];  /* zoomed depth values */
  162.    GLint maxwidth = MIN2( ctx->Buffer->Width, MAX_WIDTH );
  163.  
  164.    /* compute width of output row */
  165.    m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
  166.    if (m==0) {
  167.       return;
  168.    }
  169.    if (ctx->Pixel.ZoomX<0.0) {
  170.       /* adjust x coordinate for left/right mirroring */
  171.       x = x - m;
  172.    }
  173.  
  174.    /* compute which rows to draw */
  175.    row = y-y0;
  176.    r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
  177.    r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
  178.    if (r0==r1) {
  179.       return;
  180.    }
  181.    else if (r1<r0) {
  182.       GLint rtmp = r1;
  183.       r1 = r0;
  184.       r0 = rtmp;
  185.    }
  186.  
  187.    /* return early if r0...r1 is above or below window */
  188.    if (r0<0 && r1<0) {
  189.       /* below window */
  190.       return;
  191.    }
  192.    if (r0>=ctx->Buffer->Height && r1>=ctx->Buffer->Height) {
  193.       /* above window */
  194.       return;
  195.    }
  196.  
  197.    /* check if left edge is outside window */
  198.    skipcol = 0;
  199.    if (x<0) {
  200.       skipcol = -x;
  201.       m += x;
  202.    }
  203.    /* make sure span isn't too long or short */
  204.    if (m>maxwidth) {
  205.       m = maxwidth;
  206.    }
  207.    else if (m<=0) {
  208.       return;
  209.    }
  210.  
  211.    assert( m <= MAX_WIDTH );
  212.  
  213.    /* zoom the span horizontally */
  214.    if (ctx->Pixel.ZoomX==-1.0F) {
  215.       /* n==m */
  216.       for (j=0;j<m;j++) {
  217.          i = n - (j+skipcol) - 1;
  218.          zrgba[j][0] = rgb[i][0];
  219.          zrgba[j][1] = rgb[i][1];
  220.          zrgba[j][2] = rgb[i][2];
  221.          zrgba[j][3] = 255;
  222.          zdepth[j] = z[i];
  223.       }
  224.    }
  225.    else {
  226.       GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
  227.       for (j=0;j<m;j++) {
  228.          i = (j+skipcol) * xscale;
  229.          if (i<0)  i = n + i - 1;
  230.          zrgba[j][0] = rgb[i][0];
  231.          zrgba[j][1] = rgb[i][1];
  232.          zrgba[j][2] = rgb[i][2];
  233.          zrgba[j][3] = 255;
  234.          zdepth[j] = z[i];
  235.       }
  236.    }
  237.  
  238.    /* write the span */
  239.    for (r=r0; r<r1; r++) {
  240.       gl_write_rgba_span( ctx, m, x+skipcol, r, zdepth, zrgba, GL_BITMAP );
  241.    }
  242. }
  243.  
  244.  
  245.  
  246. /*
  247.  * As above, but write CI pixels.
  248.  */
  249. void
  250. gl_write_zoomed_index_span( GLcontext *ctx,
  251.                             GLuint n, GLint x, GLint y, const GLdepth z[],
  252.                             const GLuint indexes[], GLint y0 )
  253. {
  254.    GLint m;
  255.    GLint r0, r1, row, r;
  256.    GLint i, j, skipcol;
  257.    GLuint zindexes[MAX_WIDTH];  /* zoomed color indexes */
  258.    GLdepth zdepth[MAX_WIDTH];  /* zoomed depth values */
  259.    GLint maxwidth = MIN2( ctx->Buffer->Width, MAX_WIDTH );
  260.  
  261.    /* compute width of output row */
  262.    m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
  263.    if (m==0) {
  264.       return;
  265.    }
  266.    if (ctx->Pixel.ZoomX<0.0) {
  267.       /* adjust x coordinate for left/right mirroring */
  268.       x = x - m;
  269.    }
  270.  
  271.    /* compute which rows to draw */
  272.    row = y-y0;
  273.    r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
  274.    r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
  275.    if (r0==r1) {
  276.       return;
  277.    }
  278.    else if (r1<r0) {
  279.       GLint rtmp = r1;
  280.       r1 = r0;
  281.       r0 = rtmp;
  282.    }
  283.  
  284.    /* return early if r0...r1 is above or below window */
  285.    if (r0<0 && r1<0) {
  286.       /* below window */
  287.       return;
  288.    }
  289.    if (r0>=ctx->Buffer->Height && r1>=ctx->Buffer->Height) {
  290.       /* above window */
  291.       return;
  292.    }
  293.  
  294.    /* check if left edge is outside window */
  295.    skipcol = 0;
  296.    if (x<0) {
  297.       skipcol = -x;
  298.       m += x;
  299.    }
  300.    /* make sure span isn't too long or short */
  301.    if (m>maxwidth) {
  302.       m = maxwidth;
  303.    }
  304.    else if (m<=0) {
  305.       return;
  306.    }
  307.  
  308.    assert( m <= MAX_WIDTH );
  309.  
  310.    /* zoom the span horizontally */
  311.    if (ctx->Pixel.ZoomX==-1.0F) {
  312.       /* n==m */
  313.       for (j=0;j<m;j++) {
  314.          i = n - (j+skipcol) - 1;
  315.          zindexes[j] = indexes[i];
  316.          zdepth[j]   = z[i];
  317.       }
  318.    }
  319.    else {
  320.       GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
  321.       for (j=0;j<m;j++) {
  322.          i = (j+skipcol) * xscale;
  323.          if (i<0)  i = n + i - 1;
  324.          zindexes[j] = indexes[i];
  325.          zdepth[j] = z[i];
  326.       }
  327.    }
  328.  
  329.    /* write the span */
  330.    for (r=r0; r<r1; r++) {
  331.       gl_write_index_span( ctx, m, x+skipcol, r, zdepth, zindexes, GL_BITMAP );
  332.    }
  333. }
  334.  
  335.  
  336.  
  337. /*
  338.  * As above, but write stencil values.
  339.  */
  340. void
  341. gl_write_zoomed_stencil_span( GLcontext *ctx,
  342.                               GLuint n, GLint x, GLint y,
  343.                               const GLubyte stencil[], GLint y0 )
  344. {
  345.    GLint m;
  346.    GLint r0, r1, row, r;
  347.    GLint i, j, skipcol;
  348.    GLubyte zstencil[MAX_WIDTH];  /* zoomed stencil values */
  349.    GLint maxwidth = MIN2( ctx->Buffer->Width, MAX_WIDTH );
  350.  
  351.    /* compute width of output row */
  352.    m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
  353.    if (m==0) {
  354.       return;
  355.    }
  356.    if (ctx->Pixel.ZoomX<0.0) {
  357.       /* adjust x coordinate for left/right mirroring */
  358.       x = x - m;
  359.    }
  360.  
  361.    /* compute which rows to draw */
  362.    row = y-y0;
  363.    r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
  364.    r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
  365.    if (r0==r1) {
  366.       return;
  367.    }
  368.    else if (r1<r0) {
  369.       GLint rtmp = r1;
  370.       r1 = r0;
  371.       r0 = rtmp;
  372.    }
  373.  
  374.    /* return early if r0...r1 is above or below window */
  375.    if (r0<0 && r1<0) {
  376.       /* below window */
  377.       return;
  378.    }
  379.    if (r0>=ctx->Buffer->Height && r1>=ctx->Buffer->Height) {
  380.       /* above window */
  381.       return;
  382.    }
  383.  
  384.    /* check if left edge is outside window */
  385.    skipcol = 0;
  386.    if (x<0) {
  387.       skipcol = -x;
  388.       m += x;
  389.    }
  390.    /* make sure span isn't too long or short */
  391.    if (m>maxwidth) {
  392.       m = maxwidth;
  393.    }
  394.    else if (m<=0) {
  395.       return;
  396.    }
  397.  
  398.    assert( m <= MAX_WIDTH );
  399.  
  400.    /* zoom the span horizontally */
  401.    if (ctx->Pixel.ZoomX==-1.0F) {
  402.       /* n==m */
  403.       for (j=0;j<m;j++) {
  404.          i = n - (j+skipcol) - 1;
  405.          zstencil[j] = stencil[i];
  406.       }
  407.    }
  408.    else {
  409.       GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
  410.       for (j=0;j<m;j++) {
  411.          i = (j+skipcol) * xscale;
  412.          if (i<0)  i = n + i - 1;
  413.          zstencil[j] = stencil[i];
  414.       }
  415.    }
  416.  
  417.    /* write the span */
  418.    for (r=r0; r<r1; r++) {
  419.       gl_write_stencil_span( ctx, m, x+skipcol, r, zstencil );
  420.    }
  421. }
  422.